#define SCHEDULE_DEFS
#define SCHGTW_DEFS
#include <windows.h>

/* Notes API header files.  */

#include "lapicinc.h"

#include "global.h"
#include "nsfdata.h"
#include "nsfdb.h"
#include "nsfnote.h"
#include "nsferr.h"
#include "editods.h"
#include "stdnames.h"
#include "miscerr.h"
#include "osmem.h"
#include "oserr.h"
#include "osfile.h"
#include "schedule.h"
#include "schgtw.h"
#include "textlist.h"
#include "lapiplat.h"

/* C header files     */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>



#define MIME_PART_VERSION				2

typedef struct {
	WORD	wVersion;                 	/* MIME_PART Version */
	DWORD	dwFlags;
		#define MIME_PART_HAS_BOUNDARY			0x00000001
		#define MIME_PART_HAS_HEADERS			0x00000002
		#define MIME_PART_BODY_IN_DBOBJECT		0x00000004
		#define MIME_PART_SHARED_DBOBJECT		0x00000008	/*	Used only with MIME_PART_BODY_IN_DBOBJECT. */
		#define MIME_PART_SKIP_FOR_CONVERSION	0x00000010	/* only used during MIME->CD conversion */
	BYTE	cPartType;                	/* Type of MIME_PART body */
	BYTE	cSpare;
	WORD	wByteCount;               	/* Bytes of variable length part data
										   NOT including data in DB object*/

	WORD	wBoundaryLen;             	/* Length of the boundary string */
	WORD	wHeadersLen;              	/* Length of the headers */
	WORD	wSpare;
	DWORD	dwSpare;

	/*	Followed by the actual part data */
} MIME_PART;

DWORD       dwItem;

/* cPartType of MIME_PART */
typedef enum tagMIMEPartType
	{
	MIME_PART_PROLOG		= 1,
	MIME_PART_BODY			= 2,
	MIME_PART_EPILOG		= 3,
	MIME_PART_RETRIEVE_INFO	= 4,
	MIME_PART_MESSAGE		= 5
	} MIMEPARTTYPE;
#define OPEN_RAW_RFC822_TEXT	0x01000000	/* If set, leave TYPE_RFC822_TEXT items in native
												format.  Otherwise, convert to TYPE_TEXT/TYPE_TIME. */
#define OPEN_RAW_MIME_PART		0x02000000	/* If set, leave TYPE_MIME_PART items in native
												format.  Otherwise, convert to TYPE_COMPOSITE. */
#define OPEN_RAW_MIME	(OPEN_RAW_RFC822_TEXT | OPEN_RAW_MIME_PART)

/*
#define BUFSIZE 1000
typedef struct
{
   DWORD           dwValue;
   char *          pName;
} LITERAL_NAME_ENTRY;


#define LITERAL_TABLE_END       (0xFFFFFFFF)


LITERAL_NAME_ENTRY MimePartTypeTable [] =
{
   {MIME_PART_PROLOG,          "MIME_PART_PROLOG"},
   {MIME_PART_BODY,            "MIME_PART_BODY"},
   {MIME_PART_EPILOG,          "MIME_PART_EPILOG"},
   {MIME_PART_RETRIEVE_INFO,   "MIME_PART_RETRIEVE_INFO"},
   {MIME_PART_MESSAGE,         "MIME_PART_MESSAGE"},

      //This must be the last entry! 
   {LITERAL_TABLE_END,         "UNKNOWN MIME PART TYPE"}
};

*/

/************************************************************************

    FUNCTION:   DumpOneItem

    PURPOSE:    Print one item from a note to the dumpfile.

    ALGORITHM:  This is the action routine specified to NSFItemScan.

*************************************************************************/


FILE *dumpfile;

/************************************************************************

    FUNCTION:   DumpMimePart

************************************************************************/


void    LNPUBLIC  PrintItemString (char * pText, WORD iText)
{
   long int nChars = 0;  /* How many characters have been written out? */

   if (iText != 0)
   {
      
      while (iText--)
      {

       /* Print the next character, quoting and hexing where necessary */
         unsigned char  c = *pText++;

         if (c == '"')
         {
            fprintf (dumpfile, "\\\"");
            nChars += 2;
         }
         else if (c == '\t')
         {
            fprintf (dumpfile, "\\t");
            nChars += 2;
         }
         else if (c == '\n')
         {
            //fprintf (dumpfile, "\\n");
            /* Force a newline by lying about the number of characters */
            nChars = 99999;
         }
         else if (c == '\r')
         {
            //fprintf (dumpfile, "\\r");
            nChars += 2;
         }
         else if (c == '\0')
         {
            fprintf (dumpfile, "\\0");
            nChars += 2;
         }
         else if (c == '\\')
         {
            fprintf (dumpfile, "\\\\");
            nChars += 2;
         }
         else if ((c < 32) || (c >= 127))
         {
            fprintf (dumpfile, "\\x%02x", c);
            nChars += 4;
         }
         else
         {
            fprintf (dumpfile, "%c", c);
            nChars++;
         }

      }
   }
   return;
}
void    LNPUBLIC  DumpMimePart (char *  pData, DWORD length)
{
   char *   p = pData;
   char *   pPart;
   MIME_PART  MimePartStruct;
   long int nChars = 0;  /* How many characters have been written out? */
		
		 int i=0;
	 int start=0;

   ODSReadMemory ( &p, _MIME_PART, &MimePartStruct, 1);

   if (MIME_PART_BODY_IN_DBOBJECT & MimePartStruct.dwFlags)
      return;
	 if (MIME_PART_SHARED_DBOBJECT & MimePartStruct.dwFlags)
      return;
/*   if (MIME_PART_HAS_BOUNDARY & MimePartStruct.dwFlags)
      return;
/*
   fprintf (dumpfile, "      dwFlags (0x%lX) = ",
      MimePartStruct.dwFlags);
 /*  if (MIME_PART_HAS_BOUNDARY & MimePartStruct.dwFlags)
      fprintf (dumpfile, "MIME_PART_HAS_BOUNDARY  ");
   if (MIME_PART_HAS_HEADERS & MimePartStruct.dwFlags)
      fprintf (dumpfile, "MIME_PART_HAS_HEADERS  ");
   if (MIME_PART_BODY_IN_DBOBJECT & MimePartStruct.dwFlags)
      fprintf (dumpfile, "MIME_PART_BODY_IN_DBOBJECT  ");
   if (MIME_PART_SHARED_DBOBJECT & MimePartStruct.dwFlags)
    fprintf (dumpfile, "MIME_PART_SHARED_DBOBJECT  ");
   if (MIME_PART_SKIP_FOR_CONVERSION & MimePartStruct.dwFlags)
      fprintf (dumpfile, "MIME_PART_SKIP_FOR_CONVERSION  ");
   fprintf (dumpfile, "\n");
*/
	 if(!strstr(p,"Content-Type: text/html;"))
		 return;
	 for(i=0;i<length;i++)
		 {
				if(!strncmp("\r\n\r\n",p+i,4))
					{	
						start=i+4;
						break;
					}
		 }
   pPart = p+start;
   if (MimePartStruct.wByteCount != 0)
   {
//      PrintItemString(pPart, MimePartStruct.wByteCount-start);
   }
	 pPart[length-start-20]='\0';
   fprintf (dumpfile, "%s",pPart);

   return;
}


STATUS   LNPUBLIC   DumpOneItem( WORD       Spare,
                                 WORD       ItemFlags,
                                 char far * Name,
                                 WORD       NameLength,
                                 void far * Value,
                                 DWORD      ValueLength,
                                 void far * Parameter )
{


    char  * pData;
    WORD    length;
    WORD    wDataType;
	
/*		fprintf( dumpfile, "Item : %ld\n  Item Name   = '", ++dwItem );

    for (i=0; i<NameLength; i++)
    {
      fprintf( dumpfile, "%c", Name[i] );
    }



    fprintf( dumpfile, "'\n" );
*/

    pData = (char *) Value;
    length = (WORD) ValueLength; /* includes the 2 byte data type */

    memcpy( (char*)&wDataType, pData, sizeof(WORD) );
    pData += sizeof(WORD);
    length -= sizeof(WORD);
		/*
		if(!strncmp("h_Name",Name,NameLength))
			{
				for (i=0; i<ValueLength; i++)
				{
					fprintf( dumpfile, "%c", (char)pData[i] );
				}
				fprintf(dumpfile,"\r\n");

			}
			
*/
		if(strncmp("PageBody",Name,NameLength))
			return NOERROR;

    switch (wDataType)
    {
      case TYPE_MIME_PART:
				

				DumpMimePart( pData, length );
				break;
			}
    return( NOERROR );
}

__declspec( dllexport )int SaveMime(char *szFileName, DBHANDLE hDB, NOTEID NoteID)
{
STATUS        sError = NOERROR;
DWORD        OFlags = 0;
NOTEHANDLE		hNote;

/* Initialize Notes. */
errno_t err=0;

LAPI_INIT(sError); // LAPI_INIT is defined in lapiplat.h
if (sError)
   LAPI_INIT_ERROR;
err=fopen_s(&dumpfile,szFileName,"w");
if(err==0)
	{
		fprintf(dumpfile,"<HTML>\r\n");
		dwItem=0;
		OFlags |= OPEN_RAW_MIME_PART;

		if (NOERROR == (sError = NSFNoteOpenExt(hDB,NoteID,OFlags,&hNote)))
			{
				NSFItemScan( hNote, DumpOneItem, NULL );
				fprintf(dumpfile,"</HTML>\r\n");
				fclose(dumpfile);
				NSFNoteClose (hNote);
			}
	}

//  printf("%d fields found.\n", num_fields);

LAPI_RETURN( sError );
}

__declspec( dllexport )int GetMime(DBHANDLE hDB, NOTEID NoteID, char *szBuf, int buflen)
{
	STATUS        sError = NOERROR;
	DWORD        OFlags = 0;
	NOTEHANDLE		hNote;
	int nRead=0;
	errno_t err;


/* Initialize Notes. */
//DebugBreak();

	LAPI_INIT(sError); // LAPI_INIT is defined in lapiplat.h
	if (sError)
		 LAPI_INIT_ERROR;
	err=fopen_s(&dumpfile, "~temp.tst","w");
	if(err==0)
		{
	//		fprintf(dumpfile,"<HTML>\r\n");
			dwItem=0;
			OFlags |= OPEN_RAW_MIME_PART;

			if (NOERROR == (sError = NSFNoteOpenExt(hDB,NoteID,OFlags,&hNote)))
				{
					NSFItemScan( hNote, DumpOneItem, NULL );
		//			fprintf(dumpfile,"</HTML>\r\n");
					fclose(dumpfile);
					NSFNoteClose (hNote);
				}
		}
	err=fopen_s(&dumpfile,"~temp.tst","r");
	if(err==0)
		{
			nRead=fread(szBuf,sizeof( char ), buflen,dumpfile);
			fclose(dumpfile);
			remove("~temp.tst");
		}

//  printf("%d fields found.\n", num_fields);

return nRead;
}

/* Windows header files */

#include "windows.h"

HINSTANCE	hDllInstance = (HINSTANCE) 0;

/* Win32 DLL Startup/Shutdown routine  */

BOOL WINAPI DllMain (HANDLE hInst, ULONG dwReason,
									   LPVOID lpReserved)
{
	switch (dwReason)
	{
	case DLL_PROCESS_ATTACH:
		/* Save the instance handle */
		hDllInstance = hInst;
		break;
	
	case DLL_PROCESS_DETACH:
		break;
	}
	
	return (TRUE);
}

